home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 February: Technology Seed / Mac Tech Seed Feb '97.toast / OpenDoc 1.2b2c1 / Implementation / Memory / MemHooks.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-13  |  9.8 KB  |  330 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        MemHooks.cpp
  3.  
  4.     Contains:    Memory manager hook classes for debugging
  5.  
  6.     Owned by:    Michael Burbidge
  7.     Owned by:    Jens Alfke
  8.  
  9.     Copyright:    © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  10.  
  11.     Change History (most recent first):
  12.  
  13.          <2>     9/13/96    jpa        1371387: Speed optimizations.
  14.          <9>      8/4/95    DM        Leak checking [1267956]
  15.          <8>      5/4/95    jpa        Added AboutToAllocate.
  16.          <7>    10/24/94    jpa        Constness [1194286]
  17.          <6>     9/29/94    RA        1189812: Mods for 68K build.
  18.          <5>     9/14/94    jpa        Eliminated dependencies on rest of OpenDoc.
  19.                                     [1186692]
  20.          <4>      8/8/94    jpa        DidAllocate doesn't offset ptr if it's NULL
  21.                                     [1179564]
  22.          <3>      8/8/94    jpa        Fixed realloc hooks.
  23.          <2>      8/2/94    jpa        Now supports realloc. Also optimized some
  24.                                     code, and fed different zap values into the
  25.                                     cushion blocks when deleting.
  26.          <1>     7/26/94    jpa        first checked in
  27.          
  28.     To Do:
  29.     In Progress:
  30.         
  31. */
  32.  
  33.  
  34. #ifndef _MEMCNFIG_
  35. #include "MemCnfig.h"
  36. #endif
  37.  
  38.  
  39. #if MM_DEBUG
  40.  
  41.  
  42. #ifndef _MEMHOOKS_
  43. #include "MemHooks.h"
  44. #endif
  45.  
  46. #ifndef _PLATFMEM_
  47. #include "PlatfMem.h"
  48. #endif
  49.  
  50. #ifndef _CRAWL_
  51. #include <Crawl.h>
  52. #endif
  53.  
  54.  
  55. //==============================================================================
  56. // CBlockCushionHook
  57. //==============================================================================
  58.  
  59. //------------------------------------------------------------------------------
  60. // CBlockCushionHook::CBlockCushionHook
  61. //------------------------------------------------------------------------------
  62.  
  63. CBlockCushionHook::CBlockCushionHook()
  64. {
  65. }
  66.  
  67. //------------------------------------------------------------------------------
  68. // CBlockCushionHook::~CBlockCushionHook
  69. //------------------------------------------------------------------------------
  70.  
  71. CBlockCushionHook::~CBlockCushionHook()
  72. {
  73. }
  74.  
  75. //------------------------------------------------------------------------------
  76. // CBlockCushionHook::GetHeaderSize
  77. //------------------------------------------------------------------------------
  78.  
  79. ODBlockSize CBlockCushionHook::GetHeaderSize()
  80. {
  81.     return kPrefixCushionLength;
  82. }
  83.  
  84. //------------------------------------------------------------------------------
  85. // CBlockCushionHook::AboutToAllocate
  86. //------------------------------------------------------------------------------
  87.  
  88. ODBlockSize CBlockCushionHook::AboutToAllocate(ODBlockSize size) const
  89. {
  90.     return size + kPrefixCushionLength + kSuffixCushionLength;
  91. }
  92.  
  93. //------------------------------------------------------------------------------
  94. // CBlockCushionHook::DidAllocate
  95. //------------------------------------------------------------------------------
  96.  
  97. void* CBlockCushionHook::DidAllocate(void* blk, ODBlockSize size)
  98. {
  99.     if( blk == kMMNULL )
  100.         return kMMNULL;
  101.     else {
  102.         unsigned long *prefix
  103.             = (unsigned long *) blk;
  104.         unsigned long *suffix
  105.             = (unsigned long *) ((char *) blk + size - kSuffixCushionLength);
  106.         
  107.         *prefix++ = kPrefixCushionMagicNumber;
  108.         *prefix++ = size;
  109.         *prefix++ = kPrefixCushionMagicNumber;
  110.             
  111.         *suffix = kSuffixCushionMagicNumber;
  112.     
  113.         return (char *) blk + kPrefixCushionLength;
  114.     }
  115. }
  116.  
  117. //------------------------------------------------------------------------------
  118. // CBlockCushionHook::AboutToBlockSize
  119. //------------------------------------------------------------------------------
  120.  
  121. const void* CBlockCushionHook::AboutToBlockSize(const void* blk)
  122. {
  123.     unsigned long *prefix = (unsigned long *) ((char*)blk - kPrefixCushionLength);
  124.     
  125.     if( prefix[0]!=kPrefixCushionMagicNumber || prefix[2]!=kPrefixCushionMagicNumber )
  126.         MM_WARN("Block %p's prefix is invalid",blk);
  127.     
  128.     unsigned long *suffix = (unsigned long *)
  129.         ((char*)prefix + prefix[1] - kSuffixCushionLength);
  130.     
  131.     if( *suffix != kSuffixCushionMagicNumber )
  132.         MM_WARN("Block %p's suffix is invalid",blk);
  133.  
  134.     return prefix;
  135. }
  136.  
  137. //------------------------------------------------------------------------------
  138. // CBlockCushionHook::BasicAboutToFree
  139. //------------------------------------------------------------------------------
  140.  
  141. unsigned long* CBlockCushionHook::BasicAboutToFree(void* blk, mmboolean zap)
  142. {
  143.     unsigned long *prefix = (unsigned long *) ((char*)blk - kPrefixCushionLength);
  144.  
  145.     if( prefix[0]!=kPrefixCushionMagicNumber || prefix[2]!=kPrefixCushionMagicNumber )
  146.         MM_WARN("Block %p's prefix is invalid",blk);
  147.     
  148.     unsigned long *suffix = (unsigned long *)
  149.         ((char*)prefix + prefix[1] - kSuffixCushionLength);
  150.     
  151.     if( *suffix != kSuffixCushionMagicNumber )
  152.         MM_WARN("Block %p's suffix is invalid",blk);
  153.  
  154.     if( zap )
  155.         prefix[0] = prefix[2] = *suffix = 0xDDDDDDDD;        // Zap on free
  156.  
  157.     return prefix;
  158. }
  159.  
  160. //------------------------------------------------------------------------------
  161. // CBlockCushionHook::AboutToFree
  162. //------------------------------------------------------------------------------
  163.  
  164. void* CBlockCushionHook::AboutToFree(void* blk)
  165. {
  166.     return this->BasicAboutToFree(blk,kMMTrue);
  167. }
  168.  
  169. //------------------------------------------------------------------------------
  170. // CBlockCushionHook::AboutToRealloc
  171. //------------------------------------------------------------------------------
  172.  
  173. void CBlockCushionHook::AboutToRealloc(void* &blk , ODBlockSize &size)
  174. {
  175.     // The current block will be freed, and a new one allocated.
  176.     blk = this->BasicAboutToFree(blk,kMMFalse);        // Don't zap it, it might not get freed
  177.     size += kPrefixCushionLength + kSuffixCushionLength;
  178. }
  179.  
  180. //------------------------------------------------------------------------------
  181. // CBlockCushionHook::DidRealloc
  182. //------------------------------------------------------------------------------
  183.  
  184. void* CBlockCushionHook::DidRealloc(void* oldBlk, void* blk, ODBlockSize size)
  185. {
  186.     return this->DidAllocate(blk,size);
  187. }
  188.  
  189.  
  190. ODBlockSize CBlockCushionHook::GetBlockSize( const void* blk ) const
  191. {
  192.     unsigned long *prefix = (unsigned long *) blk;
  193.     MM_ASSERT(prefix[0]==kPrefixCushionMagicNumber && prefix[2]==kPrefixCushionMagicNumber);
  194.     return prefix[1] - (kPrefixCushionLength + kSuffixCushionLength);
  195. }
  196.  
  197.  
  198.  
  199.  
  200. //==============================================================================
  201. // CBlockStackCrawlHook
  202. //==============================================================================\
  203.  
  204.  
  205. mmboolean CBlockStackCrawlHook::gTrack;
  206.  
  207. // Global operator new/delete for StackCrawl objects
  208. void* operator new( size_t size )
  209. {
  210.     return MMAllocate(size);
  211. }
  212.  
  213. void operator delete( void* block )
  214. {
  215.     MMFree(block);
  216. }
  217.  
  218.  
  219. //------------------------------------------------------------------------------
  220. // CBlockStackCrawlHook::GetHeaderSize
  221. //------------------------------------------------------------------------------
  222.  
  223. ODBlockSize CBlockStackCrawlHook::GetHeaderSize()
  224. {
  225.     return sizeof(StackCrawl*);
  226. }
  227.  
  228. //------------------------------------------------------------------------------
  229. // CBlockStackCrawlHook::AboutToAllocate
  230. //------------------------------------------------------------------------------
  231.  
  232. ODBlockSize CBlockStackCrawlHook::AboutToAllocate(ODBlockSize size) const
  233. {
  234.     return size + sizeof(StackCrawl*);
  235. }
  236.  
  237. //------------------------------------------------------------------------------
  238. // CBlockStackCrawlHook::DidAllocate
  239. //------------------------------------------------------------------------------
  240.  
  241. void* CBlockStackCrawlHook::DidAllocate(void* blk, ODBlockSize size)
  242. {
  243.     if( blk == kMMNULL )
  244.         return kMMNULL;
  245.     else {
  246.         StackCrawl**stackCrawl = (StackCrawl**)blk;    // Points to where it's stored
  247.         if( gTrack ) {
  248.             gTrack = kMMFalse; // Disable to prevent recursion!
  249.             *stackCrawl = StackCrawl::New(3,-5);
  250.             gTrack = kMMTrue;
  251.         } else
  252.             *stackCrawl = 0;
  253.         return stackCrawl + 1;
  254.     }
  255. }
  256.  
  257. //------------------------------------------------------------------------------
  258. // CBlockStackCrawlHook::AboutToBlockSize
  259. //------------------------------------------------------------------------------
  260.  
  261. const void* CBlockStackCrawlHook::AboutToBlockSize(const void* blk)
  262. {
  263.     return ((StackCrawl**)blk) - 1;
  264. }
  265.  
  266. //------------------------------------------------------------------------------
  267. // CBlockStackCrawlHook::BasicAboutToFree
  268. //------------------------------------------------------------------------------
  269.  
  270. void* CBlockStackCrawlHook::BasicAboutToFree(void* blk, mmboolean zap)
  271. {
  272.     StackCrawl** s = (StackCrawl**)blk - 1;
  273.     if( zap ) {
  274.         delete (StackCrawl*) ((size_t)(*s) & ~3);    // Delete crawl, mask lo bits
  275.         *s = (StackCrawl*) 0xDDDDDDDD;                // Zap on free
  276.     }
  277.     return s;
  278. }
  279.  
  280. //------------------------------------------------------------------------------
  281. // CBlockStackCrawlHook::AboutToFree
  282. //------------------------------------------------------------------------------
  283.  
  284. void* CBlockStackCrawlHook::AboutToFree(void* blk)
  285. {
  286.     return this->BasicAboutToFree(blk,kMMTrue);
  287. }
  288.  
  289. //------------------------------------------------------------------------------
  290. // CBlockStackCrawlHook::AboutToRealloc
  291. //------------------------------------------------------------------------------
  292.  
  293. void CBlockStackCrawlHook::AboutToRealloc(void* &blk , ODBlockSize &size)
  294. {
  295.     // The current block will be freed, and a new one allocated.
  296.     blk = this->BasicAboutToFree(blk,kMMFalse);        // Don't zap it, it might not get freed
  297.     size += sizeof(StackCrawl*);
  298. }
  299.  
  300. //------------------------------------------------------------------------------
  301. // CBlockStackCrawlHook::DidRealloc
  302. //------------------------------------------------------------------------------
  303.  
  304. void* CBlockStackCrawlHook::DidRealloc(void* oldBlk, void* blk, ODBlockSize size)
  305. {
  306.     return this->DidAllocate(blk,size);
  307. }
  308.  
  309. //------------------------------------------------------------------------------
  310. // CBlockStackCrawlHook::GetStackCrawl
  311. //------------------------------------------------------------------------------
  312.  
  313. StackCrawl* CBlockStackCrawlHook::GetStackCrawl(const void* blk) const
  314. {
  315.     return * (StackCrawl**) blk;
  316. }
  317.  
  318. //------------------------------------------------------------------------------
  319. // CBlockStackCrawlHook::SetStackCrawl
  320. //------------------------------------------------------------------------------
  321.  
  322. void CBlockStackCrawlHook::SetStackCrawl(const void* blk, StackCrawl* s)
  323. {
  324.     * (StackCrawl**) blk = s;
  325. }
  326.  
  327.  
  328.  
  329.  
  330. #endif /*MM_DEBUG*/